﻿using System;
using System.Linq;
using System.Text.RegularExpressions;
using EntityFrameworkExtension;
using EntityFrameworkExtension.Interface;
using log4net;
using MainProcessor.Interface;


namespace MainProcessor.Caching
{
    public class DataController :IDataController
    {
        
        private readonly IDataCache dataCache;
        private readonly IRepositoryFlush repositoryFlush;

        private readonly EntityMapper<int, Guid> guidIdMapper1;
        public DataController(IDataCache dataCache, IRepositoryFlush repositoryFlush)
        {
            this.dataCache = dataCache;
            this.repositoryFlush = repositoryFlush;

            guidIdMapper1 = new EntityMapper<int, Guid>(GuidIdMapping<MutableReferenceTable1>, RefreshGuidIdMapping<MutableReferenceTable1>, CreateGuidIdMapping);
        }


        public Guid GetGuidIntMappings1(int inputId, IEfContext efContext)
        {
            return guidIdMapper1.GetTMapping(inputId, efContext);
        }
        
        
        /// <summary>
        /// The repository flush has its own database connection, so that data can be persisted in the middle of a transaction
        /// </summary>
        /// <param name="inputId"></param>
        /// <param name="efContext">not used</param>
        /// <returns></returns>
        private Guid CreateGuidIdMapping(int inputId, IEfContext efContext)
        {
            return CreateGuidIdMapping<MutableReferenceTable1>(inputId);
        }


        private Guid RefreshGuidIdMapping<T>(int inputId, IEfContext efContext) where T : class, IGuidIntMapping, IEquatable<T>
        {
            return (from x in dataCache.GetTypeMappingWithRefresh<T>(efContext)
                    where x.Id == inputId
                    select x.Guid).FirstOrDefault();
        }

        private Guid GuidIdMapping<T>(int inputId, IEfContext efContext) where T : class, IGuidIntMapping, IEquatable<T>
        {
            return (from x in dataCache.GetTypeMapping<T>(efContext)
                    where x.Id == inputId
                    select x.Guid).FirstOrDefault();
        }

        private Guid CreateGuidIdMapping<TV>(int inputId) where TV : class, IGuidIntMapping, IEquatable<TV>, new()
        {
            return repositoryFlush.CreateGuidIdMapping<TV>(inputId);
        }
    }
    
}
